<template>
  <span class="lr-input" :class="inputOptions.appendIcon ? 'appendIconSpan' : ''">
    <template v-if="['text', 'password', 'textarea', 'email', 'icon'].indexOf(inputOptions.type) !== -1">
      <el-input
        :clearable="inputOptions.clearable"
        :size="inputOptions.size"
        :style="{
          width: inputOptions.queryWidth + 'px',
          height: (inputOptions.type === 'textarea' ? inputOptions.rows : '100px')
        }"
        :placeholder="inputOptions.placeholder ? inputOptions.placeholder : '请输入' + (inputOptions.label ? inputOptions.label : '关键字')"
        v-model="inputValue"
        @blur="handleBlur"
        @keydown.tab.native="handleTab"
        @focus="handleFocus"
        @input="handleInput"
        :maxlength="inputOptions.maxlength === -1 ? 999999999999999999 : inputOptions.maxlength"
        :show-word-limit="inputOptions.maxlength ? true : false"
        :readonly="inputOptions.readonly"
        :disabled="inputOptions.disabled"
        :type="inputOptions.type"
        :rows="inputOptions.type === 'textarea' ? inputOptions.rows : 0"
        :auto-complete="inputOptions.autoComplete"
        :show-password="inputOptions.showPassword"
      >
        <template #prepend v-if="inputOptions.prependText">
          <span v-html="inputOptions.prependText"></span>
        </template>
        <template #append v-if="inputOptions.appendText">
          <span v-html="inputOptions.appendText"></span>
        </template>
        <template v-if="inputOptions.type === 'icon'" #append>
          <span class="icon-show-span">
            <i :class="'icon ' + inputValue"></i>
          </span>
          <el-popover
            ref="popoverRef"
            placement="bottom-end"
            width="300"
            trigger="click"
          >
            <div class="icon-container">
              <span
                v-for="(item, index) in fontName"
                @click="chooseIcon(item)"
                :key="index"
                class="icon-container-item"
              >
                <i :class="'icon ' + item.name"></i>
              </span>
            </div>
            <template #reference>
              <i class="icon icon-icon-arrow-down"></i>
            </template>
          </el-popover>
        </template>
        <el-button
          v-if="inputOptions.appendIcon"
          @click="iconCallBack"
          slot="append"
          class="appendIconButton"
          :icon="inputOptions.iconCode || 'Search'"
        ></el-button>
      </el-input>
    </template>
    <!-- ColorPicker 取色器 -->
    <template v-if="inputOptions.type === 'color'">
      <el-color-picker
        class="input"
        :size="inputOptions.size"
        @change="handleInput"
        :predefine="inputOptions.predefine"
        :show-alpha="inputOptions.showAlpha"
        v-model="inputValue"
        :color-format="inputOptions.colorFormat"
        :disabled="inputOptions.disabled"
      ></el-color-picker>
    </template>
    <!-- 搜索框 -->
    <template v-if="inputOptions.type === 'search'">
      <el-input
        :clearable="!inputOptions.closeInputClearable"
        :size="inputOptions.size"
        @keyup.enter.native="handleSearch"
        @input="handleSearch"
        :style="{
          width: (Number(inputOptions.openSearchSelect ? inputOptions.searchSelectWidth : 0) + Number(inputOptions.searchInputWidth)) + 'px'
        }"
        v-model="searchModel[inputOptions.searchInputField]"
        :placeholder="inputOptions.searchInputPlaceholder ? inputOptions.searchInputPlaceholder : '请输入' + inputOptions.searchInputLabel"
      >
        <template #prepend v-if="inputOptions.openSearchSelect">
          <el-select
            :popper-class="inputOptions.popperClass"
            :clearable="!inputOptions.closeSelectClearable"
            @change="handleSearch"
            :filterable="!inputOptions.closeFilterable"
            v-model="searchModel[inputOptions.searchSelectField]"
            :style="{width: inputOptions.searchSelectWidth + 'px'}"
            :placeholder="inputOptions.searchSelectPlaceholder ? inputOptions.searchSelectPlaceholder : '请选择' + inputOptions.searchSelectLabel"
          >
            <el-option
              v-for="k in inputOptions.options"
              :key="inputOptions.dicValue ? k[inputOptions.dicValue] : k.v_code"
              :readonly="k.readonly"
              :disabled="k.disabled"
              :value-id="k.id"
              :label="inputOptions.dicLabel ? k[inputOptions.dicLabel] : k.v_value"
              :value="inputOptions.dicValue ? k[inputOptions.dicValue] : k.v_code"
            ></el-option>
          </el-select>
        </template>
        <template #append>
          <el-button :icon="Search" @click="handleSearch"></el-button>
        </template>
      </el-input>
    </template>
    <!-- 数字输入框 -->
    <template v-if="inputOptions.type === 'number'">
      <span class="appendIconSpan">
        <el-input-number
          :style="{width: inputOptions.queryWidth + 'px'}"
          :size="inputOptions.size"
          class="input"
          v-model="inputValue"
          :controls-position="inputOptions.controlsPosition"
          :readonly="inputOptions.readonly"
          :disabled="inputOptions.disabled"
          :max="inputOptions.max"
          :min="inputOptions.min"
          :precision="inputOptions.precision"
          :step="inputOptions.step"
          :controls="inputOptions.controls"
          @input="handleInput"
          @change="handleInput"
        >
          <template #prefix v-if="inputOptions.prefixText">
            {{ inputOptions.prefixText }}
          </template>
          <template #suffix v-if="inputOptions.suffixText">
            {{ inputOptions.suffixText }}
          </template>
        </el-input-number>
      </span>
    </template>
    <!-- Switch开关 -->
    <template v-if="inputOptions.type === 'switch'">
      <el-switch
        :width="inputOptions.queryWidth"
        :size="inputOptions.size"
        v-model="inputValue"
        @input="handleInput"
        :readonly="inputOptions.readonly"
        :disabled="inputOptions.disabled"
        :active-value="inputOptions.activeValue ? inputOptions.activeValue : true"
        :inactive-value="inputOptions.inactiveValue ? inputOptions.inactiveValue : false"
        :active-text="inputOptions.activeText"
        :inactive-text="inputOptions.inactiveText"
      ></el-switch>
    </template>
    <!-- 多选框 -->
    <template v-if="inputOptions.type === 'checkbox'">
      <el-checkbox-group
        @change="handleInput"
        :size="inputOptions.size"
        v-model="checkboxGroupValue"
        :readonly="inputOptions.readonly"
        :disabled="inputOptions.disabled"
      >
        <el-checkbox-button
          v-for="k in inputOptions.options"
          :key="inputOptions.dicValue ? k[inputOptions.dicValue] : k.v_code"
          :value="inputOptions.dicValue ? k[inputOptions.dicValue] : k.v_code"
        >
          {{ inputOptions.dicLabel ? k[inputOptions.dicLabel] : k.v_value }}
        </el-checkbox-button>
      </el-checkbox-group>
    </template>
    <!-- 单选框 -->
    <template v-if="inputOptions.type === 'radio'">
      <el-radio-group
        v-model="radioModelValue"
        :size="inputOptions.size"
        :disabled="inputOptions.disabled"
      >
        <el-radio-button
          :key="String(inputOptions.dicValue ? k[inputOptions.dicValue] : k.v_code)"
          v-for="k in inputOptions.options"
          :value="String(inputOptions.dicValue ? k[inputOptions.dicValue] : k.v_code)"
          :readonly="k.readonly"
          :disabled="k.disabled"
        >
          {{ inputOptions.dicLabel ? k[inputOptions.dicLabel] : k.v_value }}
        </el-radio-button>
      </el-radio-group>
    </template>
  </span>
</template>

<script name="LrInput" setup>
import { Search } from "@element-plus/icons-vue";
import iconFont from "/public/iconfont/iconfont.json";
import {
  ref,
  onMounted,
  useAttrs,
  useSlots,
  computed,
  watch,
  nextTick,
} from "vue";

const slots = useSlots(); 
const attrs = useAttrs();
const props = defineProps({
  options: {
    des: "输入框配置项",
    type: Object,
    default: () => ({}),
  },
  modelValue: {
    des: "输入框配置项",
    type: [Array, String, Number, null],
    default: "",
  },
  row: {
    type: Object,
    default: () => ({}),
  },
});

const inputValue = ref(0);
const checkboxGroupValue = ref([]);
const multipleValue = ref("");
const popoverVisiable = ref(false);
const fontName = ref([]);
const select = ref("");
const searchModel = ref({});
const popoverRef = ref();
// 禁用日期的逻辑
const disabledDate = (date) => {
  if (props.options.disabledDateFn) {
    return props.options.disabledDateFn(date);
  }
};

//props的特性，它只在没有传参时才会被读取，并不会为你的参数对象补齐属性,所以用计算属性获取
const inputOptions = computed(() => {
  return Object.assign(
    {
      readonly: false, 
      disabled: false, 
      multiple: false, 
      allowCreate: false, 
      showPassword: false, 
      clearable: true, 
      type: "text", 
      controlsPosition: "right", 
      queryWidth: "auto", 
      searchSelectWidth: "130", 
      searchInputWidth: "200", 
      openSearchSelect: false, 
      max: 999999999999999999, 
      min: 0, 
      precision: 0, 
      step: 1, 
      controls: true, 
      autoComplete: "off", 
      popperClass: "", 
      showAlpha: true, 
      predefine: [], 
      rows: 3,
    },
    props.options
  );
});

const emit = defineEmits([
  "input",
  "handle-input",
  "change",
  "search",
  "icon-callback",
  "tab",
  "blur",
  "update:modelValue",
]);

const radioModelValue = computed({
  get() {
    const modelVal = inputValue.value;
    const options = inputOptions.value.options;
    const dicValue = inputOptions.value.dicValue;

    if (!options || !dicValue) {
      return String(modelVal);
    }

    let bestMatch = null;
    let matchLevel = 0; // 0:无匹配, 1:包含匹配, 2:内容匹配, 3:精确匹配

    for (const opt of options) {
      const optValue = opt[dicValue];

      // 优先级 3: 精确匹配
      if (JSON.stringify(optValue) === JSON.stringify(modelVal)) {
        bestMatch = opt;
        matchLevel = 3;
        break; // 已找到最佳匹配，无需继续
      }

      // 优先级 2: 内容匹配 (数组，忽略顺序)
      if (matchLevel < 2 && Array.isArray(modelVal) && Array.isArray(optValue) && modelVal.length === optValue.length) {
        const modelValSet = new Set(modelVal);
        if (optValue.every(item => modelValSet.has(item))) {
          bestMatch = opt;
          matchLevel = 2;
        }
      }

      // 优先级 1: 包含匹配
      if (matchLevel < 1 && Array.isArray(optValue)) {
        const valueToFind = Array.isArray(modelVal) && modelVal.length === 1 ? modelVal[0] : modelVal;
        if (!Array.isArray(valueToFind) && optValue.includes(valueToFind)) {
          bestMatch = opt;
          matchLevel = 1;
        }
      }
    }

    if (bestMatch) {
      return String(bestMatch[dicValue]);
    }

    // 回退
    return String(modelVal);
  },
  set(val) {
    const originalOption = inputOptions.value.options.find(opt => {
      const optValue = inputOptions.value.dicValue ? opt[inputOptions.value.dicValue] : (opt.Value !== undefined ? opt.Value : opt.v_code);
      return String(optValue) === val;
    });

    const valueToEmit = originalOption 
      ? (inputOptions.value.dicValue ? originalOption[inputOptions.value.dicValue] : (originalOption.Value !== undefined ? originalOption.Value : originalOption.v_code))
      : val;
      
    emit("input", valueToEmit);
    emit("handle-input", valueToEmit, inputOptions.value.field, originalOption);
    emit("change", valueToEmit);
    emit("update:modelValue", valueToEmit);
    if (typeof inputOptions.value.callback === "function") {
      inputOptions.value.callback(valueToEmit, inputOptions.value.field, originalOption);
    }
  }
});

watch(
  () => props.modelValue,
  (n) => {
    if (inputOptions.value.type === "checkbox") {
      checkboxGroupValue.value = n;
    } else if (
      inputOptions.value.multiple &&
      inputOptions.value.type === "select"
    ) {
      inputValue.value = n ? n : [];
      if (inputValue.value.length === 0) {
        multipleValue.value = "";
      }
    } else {
      inputValue.value = n;
    }
    emit("input", inputValue.value); 
    emit("handle-input", inputValue.value, inputOptions.value.field);
  },
  { deep: true, immediate: true }
);

onMounted(() => {
  inputValue.value = props.modelValue;
  if (inputOptions.value.type === "icon") {
    fontName.value = iconFont.glyphs;
    fontName.value.forEach((item) => {
      item.name = iconFont.css_prefix_text + item.font_class;
    });
  }
  if (inputOptions.value.type === "number" && !inputOptions.value.default) {
    inputOptions.value.default = 0;
  }
  if (inputOptions.value.type === "checkbox") {
    if (!inputValue.value[0] || !inputValue.value) {
      inputValue.value = [];
    }
    checkboxGroupValue.value = inputOptions.value.default
      ? inputOptions.value.default
      : [];
  }

  if (
    inputValue.value === "" ||
    ((Array.isArray(inputValue.value) ? inputValue.value.length === 0 : "") &&
      (inputOptions.value.default || inputOptions.value.default === false)) ||
    inputOptions.value.searchInputDefault ||
    inputOptions.value.searchSelectDefault
  ) {
    inputValue.value = inputOptions.value.default;
    if (inputOptions.value.type === "checkbox") {
      checkboxGroupValue.value = inputOptions.value.default
        ? inputOptions.value.default
        : [];
    }

    searchModel.value[inputOptions.value.searchInputField] =
      inputOptions.value.searchInputDefault;
    searchModel.value[inputOptions.value.searchSelectField] =
      inputOptions.value.searchSelectDefault;

    emit("input", inputValue.value); 
    emit("handle-input", inputValue.value, inputOptions.value.field);

    //赋默认值的时候触发change或者callback方法
    if (inputOptions.value.defaultChange) {
      emit("change", inputValue.value);
      if (typeof inputOptions.value.callback === "function") {
        inputOptions.value.callback(inputValue.value);
      }
    }
  }

  if (inputOptions.value.type === "switch") {
    if (inputOptions.value.activeValue) {
      if (inputValue.value === "") {
        inputValue.value = inputOptions.value.default
          ? inputOptions.value.default
          : inputOptions.value.activeValue
          ? inputOptions.value.activeValue
          : inputOptions.value.inactiveValue;
      }
    } else {
      inputValue.value = inputOptions.value.default
        ? inputOptions.value.default
        : inputValue.value
        ? true
        : false;
    }
  }
});

//加载options数据
function loadData(type = 1) {
  if (type === 1) {
    // 原代码里这里是语法错误，可根据实际需求补充逻辑，比如注释或合理代码
    // ("Empty block statement no-empty"); 
  } else {
    // getSelectData(inputOptions.value.requestOptions) //PublicParams,
    // .then((res) => {
    //   if (res.Code === 200) {
    //     set(props.options, "options", res.Data);
    //   }
    // })
    // .catch(() => {});
  }
}

//当type=search类型，每次change时触发,obj共有三个属性,分别为,inputValue,selectOptionsI
function handleSearch() {
  let optionItem = "";
  if (inputOptions.value.options) {
    inputOptions.value.options.map((item) => {
      if (
        (inputOptions.value.dicValue
          ? item[inputOptions.value.dicValue]
          : item.Value) ===
        searchModel.value[inputOptions.value.searchSelectField]
      ) {
        optionItem = item;
      }
    });
  }
  emit("input", {
    inputValue: searchModel.value[inputOptions.value.searchInputField],
    selectValue: searchModel.value[inputOptions.value.searchSelectField],
    selectOptionsItems: optionItem,
  });
  emit("change", {
    inputValue: searchModel.value[inputOptions.value.searchInputField],
    selectValue: searchModel.value[inputOptions.value.searchSelectField],
    selectOptionsItems: optionItem,
  });
  emit("search", {
    inputValue: searchModel.value[inputOptions.value.searchInputField],
    selectValue: searchModel.value[inputOptions.value.searchSelectField],
    selectOptionsItems: optionItem,
  });
}

function handleFocus(e) {
  if (typeof inputOptions.value.focus === "function") {
    inputOptions.value.focus(inputValue.value, inputOptions.value.field);
    e.srcElement.blur();
  }
}

function handleTab() {
  emit("tab", inputValue.value, inputOptions.value.field, props.row);
}

function handleBlur() {
  emit("blur", inputValue.value, inputOptions.value.field, props.row);
}

// 在输入框值inputValue改变时触发
function handleInput() {
  if (inputOptions.value.type === "checkbox") {
    inputValue.value = checkboxGroupValue.value;
  } else if (inputOptions.value.type === "week") {
    // 注意：this 指向问题，Vue 3 组合式 API 中无 this，若用 moment 需正确引入和调用
    // inputValue.value = this.$moment(inputValue.value).format("YYYY年ww周"); 
  }
  let optionItem = "";
  if (inputOptions.value.options) {
    inputOptions.value.options.map((item) => {
      if (
        (inputOptions.value.dicValue
          ? item[inputOptions.value.dicValue]
          : item.Value) === inputValue.value
      ) {
        optionItem = item;
      }
    });
  }
  emit("input", inputValue.value);
  emit("handle-input", inputValue.value, inputOptions.value.field, optionItem);
  emit("change", inputValue.value);
  emit("update:modelValue", inputValue.value);
  if (typeof inputOptions.value.callback === "function") {
    inputOptions.value.callback(inputValue.value, inputOptions.value.field, optionItem);
  }
}

//点击自定义图标时候触发
function iconCallBack() {
  if (!inputOptions.value.iconCallback) {
    if (typeof inputOptions.value.callback === "function") {
      inputOptions.value.callback(inputValue.value, inputOptions.value);
    }
  }
  if (typeof inputOptions.value.iconCallback === "function") {
    inputOptions.value.iconCallback(inputValue.value, inputOptions.value);
  }
  emit("icon-callback");
}

//选择图标
function chooseIcon(item) {
  inputValue.value = item.name;
  emit("handle-input", inputValue.value, inputOptions.value.field);
  popoverRef.value.hide();
  popoverVisiable.value = false;
}
</script>

<style scoped>
.lr-input {
  display: inline-block;
  position: relative;
}
.appendIconSpan {
  position: relative;
}
.appendIconButton {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  border: none;
  background: transparent;
  padding: 0 10px;
  cursor: pointer;
}
.icon-show-span {
  display: inline-block;
  width: 20px;
  height: 20px;
  margin-right: 5px;
  vertical-align: middle;
}
.icon-container {
  display: flex;
  flex-wrap: wrap;
  max-height: 200px;
  overflow-y: auto;
}
.icon-container-item {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  margin: 5px;
  border-radius: 4px;
  transition: all 0.3s;
}
.icon-container-item:hover {
  background-color: #f5f7fa;
}
</style>